package sil;

/**
 * Clase inmutable que contiene una colección de instancias de <code>Palabra</code>, el número total
 * de sílabas de estas palabras y las rimas sonante y consonante de la última palabra.
 * Para el conteo de sílabas tiene en cuenta las sinalefas, y la acentuación de la 
 * última palabra. Para el conteo de sílabas utiliza la clase <code>Fraseador</code>, que 
 * toma como referencia la <a href="http://es.wikipedia.org/wiki/M%C3%A9trica">wikipedia</a>
 * @author Jorge Tercero
 */
class GVerso
{
	Palabra[] palabras
	String frase
	String asonante
	String consonante
	int silabas
  
	Fraseador fraseador
	Silabeador silabeador
	
  /**
   * Construye una instancia de <code>GVerso</code> a partir de <code>frase</code>
   * @param frase String representando una frase.
   */
	GVerso(frase)
	{
    if (frase == null || frase.length()==0) throw new Exception("debes pasar como param una frase")
		fraseador = new Fraseador()
    silabeador = new Silabeador()
    this.frase = frase
		palabras = fraseador.palabrear(frase)
    if (palabras.size()==0) throw new Exception("debes pasar como param una frase")
		silabas = fraseador.cuentaSilabas(palabras)-sinalefas()
		asonante = palabras[-1].asonante()
		consonante = palabras[-1].consonante()
	}
  
  /**
   * Devuelve un entero con el número de sinalefas. Deberían restarse 
   * al total de sílabas del verso.
   */
  int sinalefas()
  {
    if (palabras.size()<2) return 0;
    
    def sinalefas = 0
    
    // itero todas las pabras hasta la penúltima
    palabras[0..-2].eachWithIndex { anterior, i ->
      
      def siguiente = palabras[i+1]
      
      if (posibleSinalefa(anterior, siguiente))
      {
        sinalefas++
      }
    }
    return sinalefas
  }
  
  /**
   * Devuelve true si <code>anterior</code> acaba en vocal y <code>siguiente</code> empieza por vocal o hache
   */
  def posibleSinalefa(anterior, siguiente)
  {
    def anteriorPattern = /.*(a|e|i|o|u|á|é|í|ó|ú)/
    def siguientePattern = /(a|e|i|o|u|á|é|í|ó|ú|h).*/
    
    return (anterior.palabra.toLowerCase()==~anteriorPattern 
      &&  siguiente.palabra.toLowerCase()==~siguientePattern)
  }
}